package org.bing.engine.utility.codec;

import java.lang.reflect.Field;
import java.util.List;

@SuppressWarnings("rawtypes")
public class PrimitiveJsonEncoder extends PrimitiveJsonBase {

    /**
     * for String type filed, not support ',' will use ' ' instead.
     */
    public String encode(Object obj) {
        if (obj == null) {
            return nullString;
        }
        if (obj instanceof List) {
            return encodeList((List) obj);
        }
        return encodeSimple(obj).toString();
    }

    private StringBuilder encodeSimple(Object obj) {
        StringBuilder sb = new StringBuilder(256);
        Class clazz = obj.getClass();
        if (super.isSupportedType(clazz)) {
            sb.append("{class:").append(typeHelper.fineClzName(clazz));
            sb.append(",value:").append(super.primitiveObjectToString(obj)).append("}");
            return sb;
        }
        SimpleReflectHelper refHelper = SimpleReflectHelper.instance(obj.getClass());
        sb.append("{class:").append(clazz.getName()).append(",");
        Field[] fds = refHelper.getTotalFields();
        int len = fds.length;
        for (int i = 0; i < len; i++) {
            Object fval = refHelper.getValue(obj, fds[i]);
            if (fval != null) { // ignore null value to out
                String fname = fds[i].getName();
                if (super.isSupportedType(fval.getClass())) {
                    sb.append(fname).append(":");
                    sb.append(super.primitiveObjectToString(fval));
                } else {
                    // encode complex type
                    sb.append(fname).append(":");
                    sb.append(encode(fval));
                }
                sb.append(",");
            }
        }
        sb.setCharAt(sb.length() - 1, '}');
        return sb;
    }

    private String encodeList(List list) {
        // encode list, {[{...},...{...}]};
        StringBuilder sb = new StringBuilder(64 * list.size());
        sb.append("{").append("[");
        for (int i = 0, len = list.size(); i < len; i++) {
            Object obj = list.get(i);
            if (i != 0) {
                sb.append(",");
            }
            sb.append(encode(obj));
        }
        sb.append("]").append("}");
        return sb.toString();
    }
}
